package me.lwn.auth.application;

import me.lwn.auth.common.PageResponse;
import me.lwn.auth.common.crud.BaseManager;
import me.lwn.auth.domain.LockedRecord;
import me.lwn.auth.infrastructure.repository.LockedRecordRepository;
import me.lwn.auth.security.web.authentication.RedisLoginLockedService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class LockedRecordManager extends BaseManager<LockedRecord, String> {

    private final LockedRecordRepository repository;
    private final RedisLoginLockedService lockedSupport;

    public LockedRecordManager(LockedRecordRepository repository, RedisLoginLockedService lockedSupport) {
        this.repository = repository;
        this.lockedSupport = lockedSupport;
    }

    public PageResponse<LockedRecord> findPage(me.lwn.auth.common.PageRequest params) {

        Page<LockedRecord> pages = repository.
                findByReleaseStatusIsNotNullAndReleaseStatusIsAfter(LocalDateTime.now(),
                        PageRequest.of((int) params.getPage() - 1, (int) params.getSize()));
        PageResponse<LockedRecord> page = new PageResponse<>(params.getPage(), pages.getSize());
        page.setTotal(pages.getTotalElements());
        page.setList(pages.getContent());
        return page;
    }

    public void release(String id) {
        repository.findById(id).ifPresent(r -> {
            lockedSupport.remove(r.getClientId(), r.getIpHost(), r.getUsername());
            r.setReleaseStatus(null);
            repository.save(r);
        });
    }

    public void releaseAll() {
        List<LockedRecord> lockedRecords = repository.findByReleaseStatusIsNotNullAndReleaseStatusIsAfter(LocalDateTime.now());
        lockedRecords.forEach(r -> {
            lockedSupport.removeAll();
            r.setReleaseStatus(null);
        });
        repository.saveAll(lockedRecords);
    }

    @Override
    protected LockedRecordRepository getRepository() {
        return repository;
    }
}